package com.example.diancai.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONArray;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.diancai.consts.RedisKeyConst;
import com.example.diancai.dto.CurrentPlayer;
import com.example.diancai.dto.Vec3DTO;
import com.example.diancai.entity.GameUser;
import com.example.diancai.entity.WxUser;
import com.example.diancai.mapper.GameUserMapper;
import com.example.diancai.mapper.WxUserMapper;
import com.example.diancai.util.AuthUtil;
import com.example.diancai.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class GameUserService extends ServiceImpl<GameUserMapper, GameUser> {

    public final static String lv2048 = "4";
    // 8行 7列
    public final static String lvXiaoXiaoLe = "7*8";

    private final static Integer xiaoxiaoleNum = 4;

    private final static Integer backNum = 3;

    @Autowired
    private WxUserService wxUserService;

    @Autowired
    @Lazy
    private AsyncService asyncService;

    public GameUser startGameUser(String gameType) {
        GameUser gameUser = new GameUser();

        if (gameType.equals("2048")) {
            gameUser.setLv(lv2048);
            List<List<Vec3DTO>> array = init2048();
            gameUser.setArray(array);

            List<List<List<Vec3DTO>>> arrayHistory = new ArrayList<>(1);
            arrayHistory.add(array);
            gameUser.setArrayHistory(arrayHistory);
        } else {
            gameUser.setLv(lvXiaoXiaoLe);
            List<List<Vec3DTO>> array = initXiaoxiaole();
            gameUser.setArray(array);

            List<List<List<Vec3DTO>>> arrayHistory = new ArrayList<>(1);
            arrayHistory.add(array);
            gameUser.setArrayHistory(arrayHistory);
        }


        gameUser.setScore(0);
        gameUser.setBackNum(backNum);
        gameUser.setGameType(gameType);
        gameUser.setCreateTime(LocalDateTime.now());
        gameUser.setWxUserId(AuthUtil.getCurrPlayerId());
        save(gameUser);
        return gameUser;
    }

    public static List<List<Vec3DTO>> initXiaoxiaole() {
        int row = Integer.parseInt(GameUserService.lvXiaoXiaoLe.split("/*")[2]);
        int column = Integer.parseInt(GameUserService.lvXiaoXiaoLe.split("/*")[0]);
        List<List<Vec3DTO>> array = new ArrayList<>(row);
        for (int i = 0; i < row; i++) {
            List<Vec3DTO> vec3DTOS = new ArrayList<>(column);
            for (int j = 0; j < column; j++) {
                int num = RandomUtil.randomInt(0, xiaoxiaoleNum);
                vec3DTOS.add(new Vec3DTO(i, j, num,new ArrayList<>()));
            }
            array.add(vec3DTOS);
        }
        return array;
    }

    public static List<List<Vec3DTO>> init2048() {
        int lv2048 = Integer.parseInt(GameUserService.lv2048);

        List<List<Vec3DTO>> array = new ArrayList<>(lv2048);

        for (int i = 0; i < lv2048; i++) {
            List<Vec3DTO> vec3DTOS = new ArrayList<>(lv2048);
            for (int j = 0; j < lv2048; j++) {
                vec3DTOS.add(new Vec3DTO(i, j, 0,new ArrayList<>()));
            }
            array.add(vec3DTOS);
        }

        randomArray(array);
        randomArray(array);
        return array;
    }

    public static void randomArray(List<List<Vec3DTO>> array) {
        Integer num = RandomUtil.randomEleList(CollUtil.newArrayList(2, 4), 1).get(0);
        int i = RandomUtil.randomInt(0, Integer.parseInt(GameUserService.lv2048));
        int j = RandomUtil.randomInt(0, Integer.parseInt(GameUserService.lv2048));
        log.info("随机,{},{},{}", i, j, num);
        if (array.get(i).get(j).getZ() != 0) {
            randomArray(array);
            return;
        }
        array.get(i).get(j).setZ(num);
    }

    public GameUser getLastGameUser(Integer currPlayerId, String gameType) {
        return lambdaQuery().eq(GameUser::getGameType, gameType).eq(GameUser::getWxUserId, currPlayerId).orderByDesc(GameUser::getCreateTime).last("limit 1").one();
    }

    public GameUser updateGameUser(GameUser gameUser) {
        WxUser wxUser = wxUserService.getById(gameUser.getWxUserId());
        CurrentPlayer currPlayer = AuthUtil.getCurrPlayer();
        if (gameUser.getGameType().equals("2048")) {
            if (gameUser.getScore() > wxUser.getGame2048MaxScore()) {
                wxUser.setGame2048MaxScore(gameUser.getScore());
                gameUser.setMaxScore(gameUser.getScore());
                currPlayer.setGame2048MaxScore(gameUser.getScore());

            }
        }
        if (gameUser.getGameType().equals("xiaoxiaole")) {
            if (gameUser.getScore() > wxUser.getGameXiaoxiaoMaxScore()) {
                wxUser.setGameXiaoxiaoMaxScore(gameUser.getScore());
                gameUser.setMaxScore(gameUser.getScore());
                currPlayer.setGameXiaoxiaoMaxScore(gameUser.getScore());
            }
        }


        asyncService.setScore(wxUser, gameUser, AuthUtil.getCurrPlayer(), AuthUtil.getToken());
        log.info("返回");
        return gameUser;
    }


}
